<?php
class TestingModel extends Model
{
    function  __construct()
    {
        parent::__construct();        
    }

    public function getExamList($studentID)
    {
        $db = DataProvider::getInstance();
        $rs = $db->query("SELECT c.id AS id, c.subjectid, s.name AS subject, semester, e.time AS time, isreal, u.id AS studentid, es.time AS totaltime, finishtime FROM classes AS c JOIN subjects AS s ON c.subjectid = s.id JOIN examstructures AS es ON s.id = es.subjectid JOIN examinfo AS e ON c.id = e.classid JOIN results AS r ON c.id = r.classid JOIN users AS u ON r.studentid = u.id WHERE isfinished = 0 AND u.id = '$studentID'");
        $objArr = array();
        while ($row = mysql_fetch_array($rs))
        {
            $objArr[] = new DataObject($row);
        }
        return $objArr;
    }

    public function getExamInfo($classID)
    {
        $db = DataProvider::getInstance();
        $rs = $db->query("SELECT r.studentid as studentid, u.name as studentname, s.name AS subject, semester, e.time AS time,
        es.time AS totaltime,
        finishtime FROM classes AS c JOIN subjects AS s ON c.subjectid = s.id JOIN examstructures AS es ON s.id = es
        .subjectid JOIN examinfo AS e ON c.id = e.classid JOIN results AS r ON c.id = r.classid JOIN users AS u ON r.studentid = u.id WHERE e.classid = $classID and finishtime is not null");
        $objArr = array();
        $row = mysql_fetch_array($rs);
        return new DataObject($row);
    }

    public function start($classID, $studentID, $subjectID, $totalTime)
    {
        $message = $this->checkTime($classID, $studentID);

        if ($message != null) return $message;

        if ( ! $this->checkExamStarted($classID, $studentID))
        {
            $this->updateFinishTime($classID, $studentID, $totalTime);
            $this->insertTempTesting($classID, $studentID, $subjectID);
        }
        return $message;
    }

    public function getQuestion($classID, $studentID, $number)
    {
        $message = $this->checkTime($classID, $studentID);

        if ($message != null) return null;

        $this->loadTable('temptesting');
        $tempTestingTableObj = new TempTestingTable();
        $condition = array('classid'=>$classID, 'studentid'=>$studentID, 'number'=>$number);
        $option = array('order'=>'number');
        $results = $tempTestingTableObj->get($condition, $option)->getAll();

        if (count($results)==0) return null;

        $this->loadTable('questions');
        $questionsTableObj = new QuestionsTable();
        $condition = array('id'=>($results[0]->questionid));
        $questions = $questionsTableObj->get($condition)->getAll();
        $questionObj = $questions[0];

        $this->loadTable('options');
        $optionsTableObj = new OptionsTable();
        $condition = array('questionid'=>($results[0]->questionid));
        $option = array('order'=>'rand()');
        $options = $optionsTableObj->get($condition, $option)->getAll();
        $questionObj->optionArr = $options;
        $questionObj->choice = $results[0]->optionid;

        return $questionObj;
    }

    public function getQuestions($classID, $studentID)
    {
        $message = $this->checkTime($classID, $studentID);

        if ($message != null) return null;
        
        $this->loadTable('temptesting');
        $tempTestingTableObj = new TempTestingTable();
        $condition = array('classid'=>$classID, 'studentid'=>$studentID);
        $option = array('order'=>'number');
        $results = $tempTestingTableObj->get($condition, $option)->getAll();

        if (count($results)==0) return null;

        $questionArr = array();

        $this->loadTable('questions');
        $questionsTableObj = new QuestionsTable();

        foreach ($results as $result)
        {
            $condition = array('id'=>($result->questionid));
            $questions = $questionsTableObj->get($condition)->getAll();
            $questionObj = $questions[0];
            $questionObj->choice = $result->optionid;
            $questionObj->number = $result->number;

            /*$this->loadTable('options');
            $optionsTableObj = new OptionsTable();
            $condition = array('questionid'=>($result->questionid));
            $options = $optionsTableObj->get($condition)->getAll();
            $questionObj->optionArr = $options;*/

            $questionArr[] = $questionObj;
        }

        return $questionArr;
    }

    public function save($classID, $studentID, $questionID, $choice)
    {
        $message = $this->checkTime($classID, $studentID);

        if ($message != null) return $message;

        $this->loadTable('temptesting');
        $tempTestingObj = new TempTestingTable();
        $tempTestingObj->set('optionid',$choice);
        $condition = array('classid'=>$classID, 'studentid'=>$studentID, 'questionid'=>$questionID);
        $tempTestingObj->update($condition);

        return $message;
    }

    public function endtest($classID, $studentID)
    {
        $message = $this->checkTime($classID, $studentID);

        if ($message != null) return $message;

        $this->updateFinishTime($classID, $studentID, 0);

        $this->loadTable('temptesting');
        $temptestingTable= new TempTestingTable();
        $condition = array('classid'=>$classID, 'studentid'=>$studentID);
        $results = $temptestingTable->get($condition)->getAll();

        $total = count($results);

        $db = DataProvider::getInstance();
        $rs = $db->query("SELECT COUNT(*) AS correct FROM options AS o JOIN temptesting AS t ON o.id = t.optionid WHERE
        classid = $classID AND studentid = $studentID AND trueorfalse = 1");
        $objArr = array();
        $row = mysql_fetch_array($rs);
        $correct = $row['correct'];

        $mark = ($correct*100)/$total;
        $mark = round($mark);

        if ($this->isReal($classID))
        {
            $this->loadTable('results');
            $resultObj = new ResultsTable(array('mark'=>$mark));
            $condition = array('classid'=>$classID, 'studentid'=>$studentID);
            $resultObj->update($condition);
        }

        return "Bạn đạt được số điểm là: $mark / 100 điểm";
    }

    private function isReal($classID)
    {
        $this->loadTable('examinfo');
        $examInfoTalble = new ExamInfoTable();
        $condition = array('classid'=>$classID);
        $rs = $examInfoTalble->get($condition)->getAll();

        $examInfo = $rs[0];
        if ($examInfo->isreal == 1) return true;
        else return false;
    }

    private function checkTime($classID, $studentID)
    {
        $message = null;
        if (count($this->getResult($classID, $studentID))==0){
            $message = 'Bạn không được thi môn này!';
            return $message;
        }

        $this->loadTable('examinfo');
        $examInfoTableObj = new ExamInfoTable();
        $condition = array('classid'=>$classID);
        $examInfoObjs = $examInfoTableObj->get($condition)->getAll();
        $exam = $examInfoObjs[0];

        $tz = new DateTimeZone('Asia/Bangkok');
        $time1 = new DateTime($exam->time, $tz);
        $time2 = new DateTime($exam->time, $tz);
        $now = new DateTime("now", $tz);

        $isStarted = $this->checkExamStarted($classID, $studentID);

        if (! $isStarted && ($now<$time1 || $now > $time1->add(new DateInterval
        ('PT20M')))){
            $message = 'Không đúng thời gian thi!';
            return $message;
        }

        $results = $this->getResult($classID, $studentID);
        $finishTime = new DateTime($results[0]->finishtime, $tz);

        if ($isStarted && ($now<$time2 || $now > $finishTime)){
            $message = 'Đã hết thời gian thi!';
            return $message;
        }
        return $message;
    }

    private function updateFinishTime($classID, $studentID, $totalTime)
    {
        $tz = new DateTimeZone('Asia/Bangkok');
        $now = new DateTime("now", $tz);
        $finishTime = $now->add(new DateInterval('PT'.$totalTime.'M'));
        $t = $finishTime->format('Y-m-d H:i:s');

        $this->loadTable('results');
        $resultObj = new ResultsTable(array('finishtime'=>$t));
        $condition = array('classid'=>$classID, 'studentid'=>$studentID);

        $resultObj->update($condition);
    }

    private function insertTempTesting($classID, $studentID, $subjectID)
    {
        $this->loadTable('tempexams');
        $tempExamObj = new TempExamsTable();
        $condition = array('subjectid'=>$subjectID);
        $option = array('order'=>'rand()');
        $examQuestions = $tempExamObj->get($condition, $option)->getAll();

        $this->loadTable('temptesting');
        $tempTestingObj = new TempTestingTable();
        $condition = array('classid'=>$classID, 'studentid'=>$studentID);
        $tempTestingObj->remove($condition);

        $number = 1;

        foreach ($examQuestions as $question)
        {
            $questionID = $question->questionid;
            $tempTestingObj->set('studentid', $studentID);
            $tempTestingObj->set('classid', $classID);
            $tempTestingObj->set('questionid', $questionID);
            $tempTestingObj->set('optionid', 'null');
            $tempTestingObj->set('number', $number++);
            //var_dump($tempTestingObj);

            $tempTestingObj->insert();
        }
    }
    
    public function getResult($classID, $studentID)
    {
        $this->loadTable('results');
        $resultTable = new ResultsTable();
        $condition = array('classid'=>$classID, 'studentid'=>$studentID);
        $results = $resultTable->get($condition)->getAll();
        return $results;
    }

    private function checkExamStarted($classID, $studentID)
    {
        $this->loadTable('results');
        $resultTable = new ResultsTable();
        $condition = array('classid'=>$classID, 'studentid'=>$studentID, 'finishtime'=>array('is not null', null));
        $exams = $resultTable->get($condition)->getAll();
        if (count($exams)>0) return true;
        else return false;
    }
}  
?>